package org.spp.voronoi;

import org.spp.utilities.Point;

import java.util.ArrayList;
import java.util.List;

/**
 * Centroid.java
 * @author Ilio Catallo, Eleonora Ciceri
 * @version 1.0
 * @see Point
 * 
 * Description: the class implements the concept of object in the vector space.
 *              Due to the fact that it can be selected and used as centroid for
 *              the next iteration, the objects are all centroids.
 * 
 * Date: Jul 10, 2011
 */
public abstract class Centroid extends Point{

    // Attributes
    protected int id;
    protected List<Centroid> adjCentroids;
    protected Cell cell;
    protected double score;
    protected double divScore;
    protected double minDist;
    
    /**
     * Constructor fro the class Centroid
     * @param coordinates
     * @param score 
     */
    public Centroid(double[] coordinates, double score){
        
        super(coordinates);
        this.adjCentroids = new ArrayList<Centroid>();
        this.score = score; 
        this.id = 0;
   
    }
    
    /**
     * Constructor for the class Centroid
     * @param coordinates
     * @param score
     * @param id 
     */
    public Centroid(double[] coordinates, double score, int id){    
        
        this(coordinates, score);
        this.id = id;
    }
    
    /**
     * Method that returns the id of the centroid
     * @return id
     */
    public int getId() {
        return id;
    }   
    
    /**
     * Method that returns the centroids adjacent to the current one
     * @return adjCentroids
     */
    public List<Centroid> getAdjCentroids(){
        return adjCentroids;
    }    
    
    /**
     * Method that returns the cell generated by the centroid
     * @return cell
     */
    public Cell getCell() {
        return cell;
    }
    
    /**
     * Method that returns the score associated to the object
     * @return 
     */
    public double getScore() {
        return score;
    }
    
    /**
     * Method that returns the diversity weighted score of the given object
     * @return divScore
     */
    public double getDivScore() {
        return divScore;
    }
    
    /**
     * Method that returns the cells adjacent to the one generated by the centroid 
     * @return adjCells
     */
    public List<Cell> getAdjCells() {
        //Variables
        List<Cell> cells = new ArrayList<Cell>();
        
        for (int i = 0; i < adjCentroids.size(); i++)
            cells.add(adjCentroids.get(i).getCell());
        
        return cells;
    }
    
    /**
     * Method that sets the list of centroids adjacent to the current one
     * @param adjCentroids 
     */
    public void setAdjCentroids(List<Centroid> adjCentroids) {
        this.adjCentroids = adjCentroids;
    }
    
    /**
     * Method that sets which cell has been generated by the centroid 
     * @param cell 
     */
    public void setCell(Cell cell) {
        this.cell = cell;
    }
    
    /**
     * Method that add an adjacent centroid to the list of adjacent centroids
     * @param adjCentroid 
     */
    public void addAdjCentroid(Centroid adjCentroid){        
        adjCentroids.add(adjCentroid);        
    }    
    
    /**
     * Method that removes all the adjacent centroids from the list
     */
    public void removeAdjCentroids() {
        adjCentroids.clear();
    }
    
    /**
     * Given the list of objects in the result set compute the diversity
     * weighted score of the object
     * @param lambda
     * @param centroids 
     */
    public void computeDivScore(double lambda, List<Centroid> centroids) {
        // Variables
        double minDist = Double.POSITIVE_INFINITY;
        
        for (int i = 0; i < centroids.size(); i++) {
            double distanceToCentroids = this.computeDistance(centroids.get(i));
            
            if (distanceToCentroids < minDist)
                minDist = distanceToCentroids;
        }
        
        divScore = (1-lambda)*score + lambda*minDist;
    }     
    
}
